﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace SdmxMailNotifier
{
    public class Global : System.Web.HttpApplication
    {
        // Constants defining the configuration directory
        private const string MAIL_FROM_PROPERTY = "MailFrom";
        private const string MAIL_FROM_DISPLAY_PROPERTY = "MailFromDisplay"; 
        private const string MAIL_SERVER_ENABLE_SSL_PROPERTY = "MailServerEnableSSL";
        private const string MAIL_SERVER_HOST_PROPERTY = "MailServerHost";
        private const string MAIL_SERVER_PORT_PROPERTY = "MailServerPort";
        private const string MAIL_SERVER_USERNAME_PROPERTY = "MailServerUsername";
        private const string MAIL_SERVER_PASSWORD_PROPERTY = "MailServerPassword";
        private const string NOTIFICATION_LOG_FILE_PROPERTY = "NotificationLogFile";
        private const string NOTIFIER_DAEMON_EXECUTION_HOUR_PROPERTY = "NotificationDaemonExecutionHour";
        private const string NOTIFIER_DAEMON_EXCUTION_PERIOD_PROPERTY = "NotificationDaemonExecutionPeriod";
        private const string USER_DIRECTORY_PROPERTY = "UsersConfiguration";

        private string GetConfigurationValue(string id, string defaultValue)
        {
            if (ConfigurationSettings.AppSettings[id] != null)
            {
                return ConfigurationSettings.AppSettings[id].ToString().Trim();
            }
            return defaultValue;
        }

        private string GetAbsolutePath(string path)
        {
            if (Path.IsPathRooted(path))
            {
                return path;
            }

            return Server.MapPath(path);
        }

        protected void Application_Start(object sender, EventArgs e)
        {
            // Init the singleton notifier shared among the web service instances
            string smtpServerHost = GetConfigurationValue(MAIL_SERVER_HOST_PROPERTY, "smtp.gmail.com");
            int smtpServerPort = int.Parse(GetConfigurationValue(MAIL_SERVER_PORT_PROPERTY, "25"));
            string mailUser = GetConfigurationValue(MAIL_SERVER_USERNAME_PROPERTY, "");
            string mailPassword = GetConfigurationValue(MAIL_SERVER_PASSWORD_PROPERTY, "");
            bool enableSSL = bool.Parse(GetConfigurationValue(MAIL_SERVER_ENABLE_SSL_PROPERTY, "false"));
            string mailFrom = GetConfigurationValue(MAIL_FROM_PROPERTY, "");
            string mailFromDisplay = GetConfigurationValue(MAIL_FROM_DISPLAY_PROPERTY, "");
            Notifier notifier = new Notifier(smtpServerHost, smtpServerPort, mailUser, mailPassword, enableSSL, mailFrom, mailFromDisplay);
            Application["Notifier"] = notifier;

            // Init the singleton users shared among the web service instances
            string usersDirectoryName = GetConfigurationValue(USER_DIRECTORY_PROPERTY, "App_Data/users/");
            UsersManager users = new UsersManager(new DirectoryInfo(GetAbsolutePath(usersDirectoryName)));
            Application["Users"] = users;

            // Initialise the scheduled notifier
            TimeSpan executionHour = TimeSpan.Parse(GetConfigurationValue(NOTIFIER_DAEMON_EXECUTION_HOUR_PROPERTY, "00:00:00"));
            TimeSpan delay = (executionHour > DateTime.Now.TimeOfDay + new TimeSpan(0, 0, 30)) ?
                executionHour - DateTime.Now.TimeOfDay : executionHour + new TimeSpan(24, 0, 0) - DateTime.Now.TimeOfDay;
            TimeSpan period = new TimeSpan(int.Parse(GetConfigurationValue(NOTIFIER_DAEMON_EXCUTION_PERIOD_PROPERTY, "1")), 0, 0, 0);
            TimerCallback callback = new TimerCallback(notifier.NotifyUsers);
            Timer notifierTimer = new Timer(callback, users, delay, period);
            Application["NotifierTimer"] = notifierTimer;

            // Initialise the log
            string logFileName = GetConfigurationValue(NOTIFICATION_LOG_FILE_PROPERTY, "App_Data/notifier.log");
            Trace.Listeners.Add(new TextWriterTraceListener(GetAbsolutePath(logFileName)));
            Trace.AutoFlush = true;
            Trace.TraceInformation("SDMX Application has been started at " + DateTime.Now.ToString());
            Trace.TraceInformation("Notifier Daemon will be executed periodically (with a period of " + period.ToString() + ") from " + (DateTime.Now + delay).ToString());
        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {
            Trace.TraceError("Error at " + DateTime.Now.ToString()+": "+e.ToString());
        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {
            Trace.TraceInformation("SDMX Application has been stopped at " + DateTime.Now.ToString());
        }
    }
}